package calendar;

import java.util.Collections;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Calendar;
import java.text.SimpleDateFormat;

/* this class creates the header for the alert table */
class AlertHeaderRenderer extends DefaultTableCellRenderer
{
  static final long serialVersionUID = 38578281L;

  boolean arrowDown = true ;
  TableCellRenderer renderer ;

  public AlertHeaderRenderer ( TableCellRenderer renderer )
  {
    super () ; 
    this.renderer = renderer ;
  }

  public Component getTableCellRendererComponent( JTable table,
                              Object value,
                              boolean isSelected,
                              boolean hasFocus,
                              int row,
                              int column )
  {
    Component c = renderer.getTableCellRendererComponent( table,
                                        value,
                                        isSelected,
                                        hasFocus,
                                        row,
                                        column ) ;
    if ( c instanceof JLabel )
    {
      c.setFont ( new Font( "Dialog", Font.BOLD, 10 ) ) ;
    }

    return c ;
  }
}

/* this class creates the alert table */
class AlertTableRenderer extends DefaultTableCellRenderer
{
  TableCellRenderer renderer ;
  static final long serialVersionUID = 4392842L;

  public AlertTableRenderer ( TableCellRenderer renderer )
  {
    super () ;
    this.renderer = renderer ;
  }

  public Component getTableCellRendererComponent( JTable table,
                              Object value,
                              boolean isSelected,
                              boolean hasFocus,
                              int row,
                              int column )
  {
    Component c = renderer.getTableCellRendererComponent( table,
                                        value,
                                        isSelected,
                                        hasFocus,
                                        row,
                                        column ) ;
    if ( c instanceof JLabel )
    {
      JLabel label = (JLabel) c ;
      label.setFont ( new Font( "Dialog", Font.BOLD, 10 ) ) ;

      int modelColumn = table.convertColumnIndexToModel ( column ) ;

      if ( modelColumn == 1 ) // colum containing alert strings
      { 
        // Create tool tip from the alert string
        TableModel model = table.getModel () ;
        String toolTip = (String) model.getValueAt ( row, modelColumn )  ;
        label.setToolTipText ( toolTip )  ;
      }
      else
      {
        // This is the time column, no tool tip necessary.
        label.setToolTipText ( null ) ;
      }
    }
    return c ;
  }
}

/* this class creates the rows in the alert table */
class AlertTableModel extends AbstractTableModel
{
  public static final int SORT_DESCENDING = 0 ; 
  public static final int SORT_ASCENDING = 1 ;
  static final long serialVersionUID = 3567592L;

  /**
  * This class represents a row in the alert table
  */
  private class TableRow implements Comparable
  {
    Object [] cells ; 

    TableRow ( double alertSeconds, String alert )
    {
      cells = new Object[1] ;
      Calendar cal = Calendar.getInstance();
      SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
      cells[0] = new String ( sdf.format( cal.getTime() ) + " -- " + alert ) ;
    }

    public int compareTo(Object o) {
      throw new UnsupportedOperationException("Not supported yet.");
    }
  }
  
  String[] columnNames ;

  int sortingDirection = SORT_DESCENDING ;
  ArrayList tableData ;

  void addAlert ( double alertSeconds, String alert )
  {
    TableRow row = new TableRow ( alertSeconds, alert ) ;

    if ( sortingDirection == SORT_DESCENDING )
    {
      tableData.add ( 0, row ) ;
    }
    else
    {
      tableData.add ( row ) ;
    }

    fireTableDataChanged () ;
  }

  AlertTableModel ()
  {
    columnNames = new String [1] ;
    columnNames[0] = "Log" ;
    tableData = new ArrayList () ;
  }

  int getSortingDirection ()
  {
    return sortingDirection ;
  }

  void sort ( int sortingDirection )
  {
    this.sortingDirection = sortingDirection ;

    if ( sortingDirection == SORT_ASCENDING )
    {
      Collections.sort ( tableData, Collections.reverseOrder() ) ;
    }
    else
    {
      Collections.sort ( tableData ) ;
    }
  }

  public int getColumnCount ()
  {
    return columnNames.length ;
  }

  public int getRowCount ()
  {
    return tableData.size () ;
  }

  public String getColumnName ( int col )
  {
    return columnNames[col] ;
  }

  public Object getValueAt ( int row, int col )
  {
    TableRow tableRow = (TableRow)tableData.get( row ) ;
    return tableRow.cells[col].toString () ;
  }

  public Class getColumnClass ( int col )
  {
    Class c = getValueAt( 0, col ).getClass () ;
    return c ;
  }

  public void clearTable ()
  {
    tableData.clear();
    fireTableDataChanged () ;
  }
}

/* this panel displays the alert table */
public class AlertPanel extends JPanel 
{
  final AlertTableModel tableModel ;
  final AlertHeaderRenderer headerRenderer ;
  final JTable table ;
  static final long serialVersionUID = 2342387L;

  public AlertPanel ()
  {
    tableModel = new AlertTableModel () ;
    table = new JTable ( tableModel ) ;
    JScrollPane scrollPane = new JScrollPane ( table ) ;

    TableCellRenderer defaultTableRenderer ;
    defaultTableRenderer = table.getDefaultRenderer ( String.class ) ;

    AlertTableRenderer tableRenderer ;
    tableRenderer = new AlertTableRenderer ( defaultTableRenderer ) ;

    table.setDefaultRenderer ( String.class, tableRenderer ) ;

    Dimension paneSize = new Dimension ( 490, 110 ) ;
    table.setPreferredScrollableViewportSize ( paneSize ) ;

    JTableHeader tableHeader = table.getTableHeader () ;

    headerRenderer = 
            new AlertHeaderRenderer ( tableHeader.getDefaultRenderer() ) ;
    tableHeader.setDefaultRenderer ( headerRenderer ) ;

    setMinimumSize ( paneSize ) ;
    setMaximumSize ( paneSize ) ;
    setPreferredSize ( paneSize ) ;

    setLayout ( new GridLayout ( 1, 1 ) ) ;
    add ( scrollPane ) ;
  }

  /* allows another object to add an alert to the table */
  void addAlert ( double alertSeconds, String alert )
  {
    tableModel.addAlert ( alertSeconds, alert ) ;
  }

  /* optional method to clear the log */
  public void clearLog ()
  {
    tableModel.clearTable();
  }
}
